using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DICE_GS;

public enum DiceShapeType
{
	None,
	Normal,
	Attacker,
	Defender,
}

public class BoardManager : MonoBehaviour {
	
	private static BoardManager instance;

	public static BoardManager Instance{
		get{
			return instance;
		}
	}	


	
	//public GameObject [] boardMapPrefab;
	
	public GameObject boardPersonPlayerPrefab;
	public GameObject boardPersonEnemyPrefab;
	public int numDice;
	public GameObject diceOverHeadPrefab;
	public List<GameObject> diceOverHead = new List<GameObject>();
	public float diceOverheadOffsetX = -0.11f;
	
	public GameObject playerNamePrefab;
	public GameObject rollButton;
	public GameObject waitingTurnUI;
	public GameObject movingSlider;
	public GameObject destMark;
	
	GameObject [] destShowEffect = new GameObject[5];
	List<GameObject> curActiveDestMark = new List<GameObject>();
	public GameObject battleWinPrefab;
	public GameObject battleLosePrefab;
	public GameObject victoryPrefab;
	public GameObject screenSimpleTextPrefab;
	public GameObject bind_front;
	public GameObject bind_back;
	public GameObject bindObj_back;
	public GameObject bindObj_front;
	public GameObject playerShadowPrefab;
	
//	public GameObject nameTagPrefab;
//	public GameObject mainCharMoveNum;
	
	public List<Color> nameTagColors;
	
	public int nDiceAddNum;
	public bool isBoardPersonMoving;
	public bool isWaitingForBoardPersonMoving;
	
	public BoardPerson personToMove;
	public bool waitRollBtnShow;
	public DateTime deadLineReserve = new DateTime();
	//public float upOffset= 0.32f;
	
	List<BoardTile> allBoardTileList = new List<BoardTile>();
	
	GameObject boardPersonPlayer;
	GameObject boardPersonEnemy;
	
	public BoardTile startBoard;
	public BoardTile endBoard;
	public float startGoalDistance;
	public bool isShowDiceUIDone;
	public bool bShowDiceNumCompleted;
	public bool isBattleDiceUIDoing;
	public bool isAttackerDiceUI;
	public bool isGameOver;
	public bool isWinGame;
	
	public List<BoardPerson> boardPersonPCList;
	public List<BoardPerson> boardPersonNPCList;
	public BoardPerson boardPerson_me;
	public int mySID;
	public bool isGlowTileForPathSelect;
	public int nCurTurn;
	public int curTurnSID;
	public int nCountShowUIRollMoveDice;
	public bool bActivatedDiceOverHead_byPlayAnim;
	//public int toBeDeletedPawnID;
	public BoardPerson hidedSpawnNPC;
	public tk2dSpriteCollectionData [] spriteCollections;
	public tk2dSpriteAnimation [] spriteAnimations;
	public bool nextTurnOK;
	public float boundRect_left=999;
	public float boundRect_right=-999;
	public float boundRect_bottom=999;
	public float boundRect_top=-999;
	public bool gameStarted;
	public bool bEscapeToBind;
	public bool bEscapeFailToBind;
	public bool bUsedTeleportSkill;
	public bool bUsedTrapDecoy;
	
	public bool bWaitForSkillShow;
	public bool bWaitForDirectionRollDone;
	public int diceValue_direction;
	public GameObject fxTileChangePrefab;
	public GameObject tombPrefab;
	GameObject diceNumObj;
	
	public GameObject cobWebTextPrefab;
	public List<SidMpPair> otherPlayerCaseRecoverMP = new List<SidMpPair>();
	public int caseMPToRecover;
	public bool bCaseRecoverMP;
	public bool bDuringRebirth;
	
	public GameObject cobwebText;
	public GameObject screenSimpleTextGo1;
	public GameObject screenSimpleTextGo2;
	
	Dictionary<UIType, string> uiString = new Dictionary<UIType, string>();

	public bool isAttackerBattleRolled;
	public RaceType curMapRaceType;
	public int lapTotal;
	public BoardPerson person_activatedDiceOverHead;
	public bool isAttackerAIThinkingShowed;
	public bool bWaitDefenderAIThink;
	//public bool bShowDiceUITest;s
	public bool bTestPauseShowDiceUI;
	public bool bWaitForUIBattleDice;
	public element elementType = element.none;
	public int runnerCnt;
	public List<BoardTile> destinationTiles = new List<BoardTile>();
	public Stack<BoardTile> boardIdsUntilDestTile = new Stack<BoardTile>();
	public Dictionary<BoardTile, List<BoardTile> > destinationTileBidDic = new Dictionary<BoardTile, List<BoardTile> >();
	int nFindDestIterationCount;
	float hitAnimDelayBetweenDice;
	public DiceShapeType curDiceShapeType = DiceShapeType.Normal;
	//public tk2dSpriteCollectionData commonBoardSpriteCollection;
	public GameObject m_bgParent;

	void Awake()
	{
		instance = this;

	
		//Screen.SetResolution(1280, 720, false);

		for(int i=0; i< 2; i++)
		{
			destShowEffect[i] = Instantiate(destMark) as GameObject;
			destShowEffect[i].name = "destmark";
			destShowEffect[i].SetActive(false);
		}

		bindObj_back = Instantiate(bind_back) as GameObject;
		bindObj_front = Instantiate(bind_front) as GameObject;
		bindObj_back.SetActive(false);
		bindObj_front.SetActive(false);
		
		cobwebText = Instantiate( cobWebTextPrefab) as GameObject;
		cobwebText.GetComponent<UILabel>().text = CStringTableManager.Instance.GetItemById(1708);
		cobwebText.SetActive(false);
		
		screenSimpleTextGo1 = Instantiate(screenSimpleTextPrefab) as GameObject;
		screenSimpleTextGo1.SetActive(false);
		
		//screenSimpleTextGo2 = Instantiate(screenSimpleTextPrefab) as GameObject;
		//screenSimpleTextGo2.SetActive(false);
		
		uiString.Add (UIType.UI_AVOID, CStringTableManager.Instance.GetItemById(1661) );
		uiString.Add (UIType.UI_BLOCK, CStringTableManager.Instance.GetItemById(1662) );
		uiString.Add (UIType.UI_CHASE, CStringTableManager.Instance.GetItemById(1663) );
	}
	
	
	// Use this for initialization
	void Start () {
//        LoadingWindow.window.ShowShortLoading();
		glog.debug ("boardmanager start");
		nameTagColors.Add ( new Color(242/255.0f,223/255.0f, 51/255.0f,1.0f )) ;
		nameTagColors.Add ( new Color(57/255.0f,223/255.0f, 51/255.0f,1.0f )) ;
		nameTagColors.Add ( new Color(217/255.0f, 79/255.0f, 79/255.0f,1.0f )) ;
		nameTagColors.Add ( new Color(100/255.0f, 87/255.0f, 206/255.0f,1.0f )) ;
		nameTagColors.Add ( new Color(69/255.0f,106/255.0f, 255/255.0f,1.0f )) ;
		nameTagColors.Add ( new Color(230/255.0f,124/255.0f, 84/255.0f,1.0f )) ;

        StartCoroutine("Co_InitBoard");
        //InitBoard();
		SoundManagerCommon.Instance.StopBGM();
		SoundManagerCommon.Instance.PlayBGM(0);
	}

    IEnumerator Co_InitBoard()
    {
        yield return null;
		
		nextTurnOK = true;
		StageManagerWrapper.isBoardManagerInit = true;
        isGameOver = false;
        isWinGame = false;
		CMapData mapdata = CMapDataManager.Instance.GetMapData(CSceneManager.m_mapName);
		curMapRaceType = mapdata.race_type;
		lapTotal = mapdata.lap;
        glog.debug("Init Board " + Time.time);
		GameObject prefabMapToLoad = null;
		
		elementType = CSceneManager.m_themeType;
		//if(CSceneManager.isReplay )//&& !CSceneManager.isIngameTutorial)
		//	elementType = CSceneManager.manager.testThemeType;
		// for temporarily
		//if(CSceneManager.m_mapName == "map_demo01" || CSceneManager.m_mapName == "map_demo03")
		//	elementType = element.sky;

		foreach(MapList mapNameType in Enum.GetValues(typeof(MapList)) )
		{
			string nameMap = String.Format("map_"+mapNameType.ToString() );
			if(nameMap == CSceneManager.m_mapName)
			{
				glog.debug("Loading tiles..  ");
				float timeStart = Time.time;	


//				if(elementType != element.none)
//				{
//					LTPrefabManager.InstantiateMap(String.Format( nameMap +"_"+ elementType.ToString() ), false,"");
//				}
//				else
//					LTPrefabManager.InstantiateMap(nameMap,false,"");
				GameObject mapBoardInfoGo = Instantiate( Resources.Load("Prefabs/Board/board_"+nameMap) as GameObject ) as GameObject;
				GameObject themeRes = Resources.Load("Prefabs/Map_theme/"+elementType.ToString()) as GameObject;

//				GameObject startTilePosGo = Resources.Load("Prefabs/BoardStartTilePos/StartTilePos_"+ nameMap) as GameObject;
//				StartTilePosInfo startPosInfo = null;
//				if(startTilePosGo!=null)
//					startPosInfo = startTilePosGo.GetComponent<StartTilePosInfo>();

				SpriteResManager resMgr = themeRes.GetComponent<SpriteResManager>();
				MapBoardInfo mapBoardInfo = mapBoardInfoGo.GetComponent<MapBoardInfo>();

				GameObject pathMgrGo = new GameObject();
				PathManager pathManager = pathMgrGo.AddComponent<PathManager>();
				pathManager.nMaxX=mapBoardInfo.nMaxX;
				pathManager.nMaxY=mapBoardInfo.nMaxY;
				pathManager.boardCount=mapBoardInfo.boardCount;
				pathManager.Init();
				pathMgrGo.name = "PathManager";
				pathMgrGo.tag = "Path Manager";
				pathMgrGo.transform.parent = mapBoardInfoGo.transform;

				BoardTile.ClearEff();
				int nBInfoCount=0;
				BoardTile startTile = null;
				BoardTile goalTile = null;
				foreach(BoardInfo binfo in mapBoardInfo.boardInfoList)
				{
					GameObject boardGo = new GameObject();
					BoardTile bt = boardGo.AddComponent<BoardTile>();
					tk2dSprite boardSprite = boardGo.AddComponent<tk2dSprite>();
					boardSprite.SetSprite( resMgr.collection , BoardTile.GetModelName(binfo.tilename, elementType )  );
					boardSprite.scale = new Vector3(0.1f,0.1f,0.1f);
					boardSprite.renderer.sortingLayerName = "Board";
					bt.boardInfo = binfo;
					boardGo.name= "BoardTile_"+binfo.id+"_"+binfo.index_x+"_"+binfo.index_y;
					boardGo.transform.parent = mapBoardInfoGo.transform;
					boardGo.transform.position= new Vector3( binfo.x, binfo.y, binfo.z);

//					if(startPosInfo!=null)
//					{
//						if(binfo.isStart)
//							boardGo.transform.position =  startPosInfo.GetPos(true, elementType , boardGo.transform.position);
//						else if(binfo.isGoal)
//							boardGo.transform.position = startPosInfo.GetPos(false, elementType , boardGo.transform.position);
//					}
					if(binfo.isStart)
						startTile = bt;
					if(binfo.isGoal)
						goalTile = bt;

					boardGo.tag = "Board Tile";
					bt.Init();
					nBInfoCount++;
					if(nBInfoCount>20)
					{
						nBInfoCount=0;
						yield return null;
					}
				}



				int index_dx_start = 0;
				int index_dy_start = 0;
				int index_dx_goal = 0;
				int index_dy_goal = 0;
				foreach(BoardInfo binfo in mapBoardInfo.boardInfoList)
				{
					if(startTile!=null)
					{
						if(binfo.index_x == startTile.boardInfo.index_x+1 && binfo.index_y== startTile.boardInfo.index_y)
							index_dx_start = 1;
						if(binfo.index_y == startTile.boardInfo.index_y+1 && binfo.index_x== startTile.boardInfo.index_x)
							index_dy_start = 1;
						if(binfo.index_x == startTile.boardInfo.index_x-1 && binfo.index_y== startTile.boardInfo.index_y)
							index_dx_start = -1;
						if(binfo.index_y == startTile.boardInfo.index_y-1 && binfo.index_x== startTile.boardInfo.index_x)
							index_dy_start = -1;
					}
					if(goalTile!=null)
					{
						if(binfo.index_x == goalTile.boardInfo.index_x+1 && binfo.index_y== goalTile.boardInfo.index_y)
							index_dx_goal = 1;
						if(binfo.index_y == goalTile.boardInfo.index_y+1 && binfo.index_x== goalTile.boardInfo.index_x)
							index_dy_goal = 1;
						if(binfo.index_x == goalTile.boardInfo.index_x-1 && binfo.index_y== goalTile.boardInfo.index_y)
							index_dx_goal = -1;
						if(binfo.index_y == goalTile.boardInfo.index_y-1 && binfo.index_x== goalTile.boardInfo.index_x)
							index_dy_goal = -1;
					}
				}
				if(startTile!=null)
					BoardTile.SetStartGoalTilePos(elementType, startTile, index_dx_start, index_dy_start);
				if(goalTile!=null)
					BoardTile.SetStartGoalTilePos(elementType, goalTile, index_dx_goal, index_dy_goal);

				mapBoardInfo.boardInfoList.Clear();
				

				yield return new WaitForEndOfFrame();
				glog.debug( "Loading tiles done  "+(Time.time-timeStart).ToString("0.00") );
				glog.debug("Loading back..  ");
				timeStart = Time.time;
				if(elementType != element.none)
				{
					//LTPrefabManager.InstantiateMap(nameMap,true,"_back_"+ elementType.ToString() +"_object");
					m_bgParent = LTPrefabManager.InstantiateMap("",true,"back_"+ elementType.ToString() +"_obj");
				}
				else
					LTPrefabManager.InstantiateMap(nameMap,true,"_back");
				yield return new WaitForEndOfFrame();
				glog.debug("Loading back done  "+(Time.time-timeStart).ToString("0.00") );
				glog.debug("Loading bgObject..  ");
				timeStart = Time.time;
				if(elementType == element.none)
					LTPrefabManager.InstantiateMap(nameMap,true,"_bgObject");
				yield return new WaitForEndOfFrame();
				glog.debug("Loading bgObject done  "+(Time.time-timeStart).ToString("0.00") );
				break;
			}
		}



		if(elementType != element.none)
		{
			GameObject tmpPrefab = Resources.Load("Prefabs/Map_back/"+elementType.ToString()+"_bg") as GameObject;
			if(tmpPrefab!=null)
			{
				GameObject bgSky = Instantiate(  tmpPrefab ) as GameObject;

				bgSky.transform.parent = Camera.main.gameObject.transform;
				bgSky.transform.localPosition = tmpPrefab.transform.position;
				bgSky.transform.localRotation = tmpPrefab.transform.rotation;
				bgSky.transform.localScale = tmpPrefab.transform.localScale;
				Camera.main.gameObject.GetComponent<CameraControl>().InitSkyBgScale(bgSky);
				//bgSky.AddComponent<CameraAttachedBG>();
				//bgSky.AddComponent<BoxCollider>();
				//bgSky.layer = LayerMask.NameToLayer("back_cameraBG");
			}
		}
		
		//LTPrefabManager.InstantiateC(PrefabTypes.LoadingWindow) as GameObject;
		
//        foreach (GameObject go in boardMapPrefab)
//        {
//            if (go.name == CSceneManager.m_mapName)
//            {
//				prefabMapToLoad = go;
//                break;
//            }
//        }
//		
//		if(prefabMapToLoad!=null)
//		{
//			GameObject mapGo = new GameObject(prefabMapToLoad.name);
//			
//			foreach(Transform child in prefabMapToLoad.transform)
//			{
//				GameObject mapPart = Instantiate(child.gameObject) as GameObject;
//				mapPart.transform.parent = mapGo.transform;
//				
//				glog.debug(mapPart.name+"   load complete " + Time.time);
//				yield return null;
//			}
//		}
		
//		if(prefabMapToLoad!=null)
//		{
//			GameObject mapGo = new GameObject(prefabMapToLoad.name);
//			
//			foreach(Transform child in prefabMapToLoad.transform)
//			{
//				GameObject partGo = new GameObject(child.gameObject.name);
//				foreach(Transform childObj in child)
//				{
//					GameObject obj = Instantiate(childObj.gameObject) as GameObject;
//					obj.transform.parent = partGo.transform;
//					glog.debug("load obj "+obj.name);
//					yield return null;
//				}
//				glog.debug(partGo.name+"   load complete " + Time.time);
//				partGo.transform.parent = mapGo.transform;
//				yield return null;
//			}
//		}
		System.GC.Collect();
		Resources.UnloadUnusedAssets();
        glog.debug("Init Board complete " + Time.time);
        hidedSpawnNPC = null;

        numDice = 2;
        for (int i = 0; i < numDice; i++)
        {
            GameObject go = Instantiate(diceOverHeadPrefab) as GameObject;
            diceOverHead.Add(go);
            go.SetActive(false);
        }
        
		yield return new WaitForSeconds(0.5f);
		
		//CNetworkManager.Instance.SendRequest("StageData");// should call after all loading done...
		PC_CS_REQUEST_STAGE_DATA packet = new PC_CS_REQUEST_STAGE_DATA();
		//CNetworkManager.Instance.SendPacket(packet.Protocol, packet.GetParam());		
		CNetworkManager.Instance.SendPacket(packet);	
		
		yield return new WaitForSeconds(0.5f);
		
		CameraControl camControl = Camera.main.gameObject.GetComponent<CameraControl>();
		camControl.SetBoundary(boundRect_left-0.5f, boundRect_right+0.5f, boundRect_bottom-0.5f, boundRect_top+0.5f);
		if(!StageManagerWrapper.bTurnStarted && !StageManagerWrapper.bContinueTurnStarted)
		{
			if(boardPerson_me!=null)
			{
				camControl.SetCameraFocus(boardPerson_me.transform);
				camControl.ChangeInstant();
			}
		}
		UIPanel panel = StageManagerWrapper.manager.loadingPanel;
		GameObject lodingDice = panel.transform.FindChild("DIceOverhead").gameObject;
		lodingDice.SetActive(false);
		while(panel.alpha>0)
		{
			panel.alpha -= Time.deltaTime*2.0f;
			if(panel.alpha<0)
				panel.alpha=0;
			yield return null;
		}
		StageManagerWrapper.manager.loadingPanel.gameObject.SetActive (false);
		panel.alpha = 1;
		lodingDice.SetActive(true);
//		yield return new WaitForSeconds(1.0f);
//		Camera.main.gameObject.GetComponent<CameraControl>().SetCameraFocus(boardPerson_me.transform);
//		LoadingWindow.window.HideLoading();
		yield return new WaitForSeconds(0.1f);
		gameStarted = true;
		if(StageManagerWrapper.is_PVE)
		{
        	PC_OP_GAME_START packetStart = new PC_OP_GAME_START();
			CNetworkManager.Instance.SendPacket(packetStart);
		}
    }

//	void InitBoard() {
//		isGameOver = false;
//		isWinGame = false;
//		glog.debug("Init Board "+Time.time);
//		foreach(GameObject go in boardMapPrefab) 
//		{
//			if(go.name == CSceneManager.m_mapName) {
//				Instantiate(go);
//				break;
//			}
//		}
//		glog.debug("Init Board complete "+Time.time);
//		hidedSpawnNPC = null;
//		
//		numDice = 2;
//		for(int i=0; i<numDice;i++)
//		{
//			GameObject go = Instantiate(diceOverHeadPrefab) as GameObject;
//			diceOverHead.Add ( go   );
//			go.SetActive(false);
//		}
//        LoadingWindow.window.HideLoading();
//	}
	
	public void AddBoardTile(BoardTile board)
	{
		//glog.debug ("add boardtile "+board.boardInfo.id+ "  "+Time.time);
		if(board.boardInfo.isStart)
			startBoard = board;
		if(board.boardInfo.isGoal)
			endBoard = board;
		allBoardTileList.Add(board);
		
		if(allBoardTileList.Count == PathManager.Instance.boardCount)
		{
			//startGoalDistance = (startBoard.transform.position - endBoard.transform.position).magnitude;
			glog.debug ("pathmanager path set");
			foreach( BoardTile bt in allBoardTileList)
			{
				PathManager.Instance.boardTiles[bt.boardInfo.index_x, bt.boardInfo.index_y] = bt;
				PathManager.Instance.AddBoardDic(bt.boardInfo.id, bt);

				
			}	
		
		}
		if(board.transform.position.x < boundRect_left)
			boundRect_left = board.transform.position.x;
		if(board.transform.position.x > boundRect_right)
			boundRect_right = board.transform.position.x;
		if(board.transform.position.y < boundRect_bottom)
			boundRect_bottom = board.transform.position.y;
		if(board.transform.position.y > boundRect_top)
			boundRect_top = board.transform.position.y;
		
	}
	
	public void CheckNextTurnOK()
	{
		StartCoroutine("CoCheckNextTurnOK");
	}
	
	IEnumerator CoCheckNextTurnOK()
	{
		yield return new WaitForSeconds(4.0f);
		while(!isShowDiceUIDone)
			yield return null;
		nextTurnOK = true;
	}
	
	public void ShowDiceUIBattle(BoardPerson person, byte [] nDice , byte [] addNumList, bool isAttacker)
	{
		glog.debug(person.SID+"  ShowDiceUIBattle "+isAttacker);
		isAttackerDiceUI = isAttacker;
		if(person.tagOverHead!=null)
			person.tagOverHead.SetActive(false);
		HideCurActiveDestMark();
		StageManagerWrapper.camControl.BackToDefaultOrtho();
		ShowDiceUI(person, nDice, addNumList, true);
	}

	public void ShowDiceUI(BoardPerson person, byte [] nDice , byte [] addNumList, bool _isBattleDiceUI)
	{
		isBattleDiceUIDoing = _isBattleDiceUI;
		isShowDiceUIDone = false;
		bShowDiceNumCompleted = false;

		StartCoroutine(ShowDiceNum(person, nDice, addNumList, _isBattleDiceUI ) );

	}
	
	public PlayMakerFSM FindFsm(GameObject obj, string nameFsm)
	{
		PlayMakerFSM [] fsmList = obj.GetComponents<PlayMakerFSM>();
		foreach( PlayMakerFSM fsm in fsmList)
		{
			if(fsm.Fsm.Name == nameFsm)
				return fsm;
		}		
		return null;
	}
	
	public void RestartFSM(GameObject obj,string nameFsm)
	{
		glog.debug("RestartFSM "+nameFsm);
		RestartFSM( FindFsm(obj,nameFsm));	
	}
	
	public void RestartFSM(PlayMakerFSM playMakerFSM)
	{
		bool bRestartOnEnable = playMakerFSM.Fsm.RestartOnEnable;
		playMakerFSM.Fsm.RestartOnEnable =  true;
		playMakerFSM.enabled = true;
		playMakerFSM.Fsm.Stop();
		playMakerFSM.Fsm.Start ();		
		playMakerFSM.Fsm.RestartOnEnable =  bRestartOnEnable;
	}
	
	public void StopFSM(GameObject obj,string nameFsm)
	{
		PlayMakerFSM playMakerFSM = FindFsm(obj,nameFsm);
		playMakerFSM.enabled = false;
		playMakerFSM.Fsm.Stop();
	}
	
	IEnumerator ShowDiceNum(BoardPerson person, byte [] nDiceList ,byte [] addNumList, bool _isBattleDiceUI)
	{	
		if(diceNumObj!=null)
			diceNumObj.SetActive(false);
		if(_isBattleDiceUI)
		{
			if(nDiceList==null || nDiceList.Length==0)
			{
				while(StageManagerWrapper.manager.battleDiceList== null || StageManagerWrapper.manager.battleDiceList.Length == 0)
				{
					person.isWaitingBattleDiceList = true;
					yield return null;
				}
				person.isWaitingBattleDiceList = false;
				nDiceList = new byte[StageManagerWrapper.manager.battleDiceList.Length];
				for(int i=0; i< StageManagerWrapper.manager.battleDiceList.Length; i++)
					nDiceList[i] = StageManagerWrapper.manager.battleDiceList[i];
				StageManagerWrapper.manager.battleDiceList = null;
			}

			StageManagerWrapper.manager.battleDiceList = null;

			while(person.isFalling)
				yield return null;

			if(isAttackerDiceUI)
			{
			//	SetDiceTexture(DiceShapeType.Attacker);
				// exception case :  in case didn't get combat info , dont make attack dice twice
				if(person != BattleManager.Instance.attacker && BattleManager.Instance.attackerNum.activeSelf)
				{
					Debug.LogError("not exist combat info. force set defender");
					isAttackerDiceUI = false;
				}
			}
			else
			{
			//	SetDiceTexture(DiceShapeType.Defender);
			}

			if(isAttackerDiceUI)
			{
				if(!person.bMovedToBattlePosition)
				{
					person.MoveToAttackerPos();
					yield return new WaitForSeconds(0.5f);
				}	
				if(person.battleOpponent!=null && person.battleOpponent.IsPC_or_AI() )
					BoardTile.DeleteAllMovingCourse();

				ActivateDiceOverHead(person, DiceShapeType.Attacker);
			}
			else
			{
				//while(!person.bFaceToAttacker)
				//{
				//	yield return null;
				//}
			}
		}
		else
		{
		//	SetDiceTexture(DiceShapeType.Normal);
		}

		HudManager.Instance.SetTurnTimeCount(person.SID,false);

		while(person.bCastedSkill)
			yield return null;

		if(person.skillIconOverHead != null)
		{
			person.skillIconOverHead.GetComponent<SpriteManipulate>().ChangeAlphaDelay(0,2.5f,0.7f,true);
			person.skillIconOverHead = null;
		}
		
		person.PlayDiceHitAnim(nDiceList);
		
		while(!person.bDiceHitTriggered)
			yield return null;

		int nDice = 0;
		bool isDouble = false;
		if(nDiceList.Length==2 && nDiceList[0] == nDiceList[1])
			isDouble=true;

		foreach (byte b in nDiceList)
		{
			nDice += b;
		}
		//int nDice = (int)nDiceList.Sum();

		float delay = GetDiceOverHeadAnimLength();
		glog.debug ("showdicenum delay="+delay);
		yield return new WaitForSeconds(delay+hitAnimDelayBetweenDice);
		//person.RestoreDiceOverHeadParent();
		if(isDouble && (_isBattleDiceUI || bEscapeToBind) ) {
			Vector3 doubleEffPos = person.transform.position;
			doubleEffPos.y += person.overHeadDiceNumOffset;
			EffectManager.Instance.DoubleEffect(doubleEffPos);
		}
		
		/*
		if( nDice < 10) {
			NGUITools.SetActive(diceOneNum, false);
			NGUITools.SetActive(diceNumLabel,true);
			diceNumLabel.transform.localPosition = diceOneDigitPos.localPosition;
			UISprite diceNumSprite = diceNumLabel.GetComponent<UISprite>();
			diceNumSprite.spriteName = "number_" + nDice.ToString();
			diceNumSprite.MakePixelPerfect();
			//glog.debug("restartonenable="+diceNumLabel.GetComponent<PlayMakerFSM>().Fsm.RestartOnEnable);
			RestartFSM(diceNumLabel.GetComponent<PlayMakerFSM>());
			//diceNumLabel.GetComponent<PlayMakerFSM>().enabled = true;
			//diceDigit[nDice].GetComponent<TweenScale>().scale = diceDigit[nDice].GetComponent<TweenScale>().from;
			//TweenScale.Begin(diceDigit[nDice],0.2f, diceDigit[nDice].GetComponent<TweenScale>().to);
		}
		else
		{
			NGUITools.SetActive(diceOneNum, true);
			RestartFSM(diceOneNum.GetComponent<PlayMakerFSM>());
			//diceOneNum.GetComponent<PlayMakerFSM>().enabled = true;
			yield return new WaitForSeconds(0.1f);
			NGUITools.SetActive(diceNumLabel,true);
			diceNumLabel.transform.localPosition = diceTwoDigitPos.localPosition;
			UISprite diceNumSprite = diceNumLabel.GetComponent<UISprite>();
			diceNumSprite.spriteName = "number_" + (nDice-10).ToString();
			diceNumSprite.MakePixelPerfect();			
			RestartFSM(diceNumLabel.GetComponent<PlayMakerFSM>());
			//diceNumLabel.GetComponent<PlayMakerFSM>().enabled = true;
			
		}*/
		
		nDiceAddNum = 0;
		
		//for test
//		addNumList = new int[3];
//		addNumList[0] = 1;
//		addNumList[1] = 2;
//		addNumList[2] = 3;
		
		if(addNumList!=null) {
			foreach(int n in addNumList)
				nDiceAddNum += n;
		}
		
		float offset_y = person.overHeadDiceNumOffset;//0.5041599f;//0.5899644f;

		GameObject battleNum = null;
		Vector3 battleNumPos = Vector3.zero;
		if(_isBattleDiceUI)
		{
			if(isAttackerDiceUI)
			{
				for(int i=0; i< nDiceList.Length; i++)
					BattleManager.Instance.SetAttackerDice(i, (int)nDiceList[i], nDiceList.Length);
				battleNum = BattleManager.Instance.ShowBattleNum_Attacker(person, nDice);
				SoundManager.Instance.PlaySoundDiceNum(nDice);
			}
			else
			{
				for(int i=0; i< nDiceList.Length; i++)
					BattleManager.Instance.SetDefenderDice(i, (int)nDiceList[i], nDiceList.Length);
				battleNum = BattleManager.Instance.ShowBattleNum_Defender(person, nDice);
				SoundManager.Instance.PlaySoundDiceNum(nDice);
			}
			battleNumPos = battleNum.transform.position;
			battleNum.transform.parent = person.transform;
			if(nDice>9)
				battleNum.transform.localPosition = new Vector3(IngameSetting.Instance.digit2Offset, offset_y, -3);
			else
				battleNum.transform.localPosition = new Vector3(0, offset_y, -3);
		}
		else
		{
			diceNumObj = UIManager.Instance.ShowDiceNumAbovePerson(person, nDice, nDiceAddNum, true);//, offset_y);
			SoundManager.Instance.PlaySoundDiceNum(nDice);
			SoundManager.Instance.PlaySound(3);
		}
		//dice icon
		/*
		Vector3 newPos = diceNum.transform.position;
		newPos.x -= 0.17f;
		newPos.y += 0.06f;
		DiceIcon diceIcon1 = new DiceIcon();
		diceIcon1.Activate( Instantiate(BattleManager.Instance.diceIconPrefab, newPos, Quaternion.identity) as GameObject , nDice1, 0);
		
		DiceIcon diceIcon2 = new DiceIcon();
		newPos.y -= 0.06f;
		newPos.y -= 0.06f;
		diceIcon2.Activate( Instantiate(BattleManager.Instance.diceIconPrefab, newPos, Quaternion.identity) as GameObject , nDice2, 1);		
		*/
		
		float timeAdd = 0.0f;
		int nCount=0;
		while(nDiceAddNum>0)
		{
			timeAdd += Time.deltaTime;
			if(timeAdd > 0.1f) 
			{
				if(nCount==0)
				{
					for(int i=0; i< addNumList.Length; i++) {
						int addValue = addNumList[i];
						//if(i==0) {
						//	addValue += addNumList[addNumList.Length-1];
						//}
						if(addValue>0) 
						{
							if(person == boardPerson_me)
								MainHUDUI.Instance.ShowMoveBonus(person, diceNumObj.transform, i, "number_", addValue, false, DiceShapeType.Normal);
							else if(person.isBoss)
								MainHUDUI.Instance.ShowMoveBonus(person, diceNumObj.transform, i, "number_", addValue, true, DiceShapeType.Normal);
						//	else if(person.SID == EnemyUnitUI.Instance.mySID)
						//		EnemyUnitUI.Instance.ShowMoveBonus(person.transform, 0,offset_y,  diceNum.transform, i, "number_", addValue, true);
						}
					}
					//NGUITools.SetActive(mainCharMoveNum,true);
					//mainCharMoveNum.GetComponent<UILabel>().text = "+"+nDiceAddNum.ToString();
					//mainCharMoveNum.GetComponent<TweenAlpha>().alpha = mainCharMoveNum.GetComponent<TweenAlpha>().from;
					//TweenAlpha.Begin( mainCharMoveNum, 1.0f, mainCharMoveNum.GetComponent<TweenAlpha>().to);
					//mainCharMoveNum.GetComponent<TweenPosition>().position = mainCharMoveNum.GetComponent<TweenPosition>().from;
					//TweenPosition.Begin( mainCharMoveNum, 1.0f, mainCharMoveNum.GetComponent<TweenPosition>().to);
					glog.debug("addNumList.Length="+addNumList.Length);
					float waitSec = addNumList.Length * 0.1f;
					yield return new WaitForSeconds(0.8f);//waitSec);
					yield return new WaitForSeconds(IngameSetting.Instance.MoveBonusDelay);
				}
				
				SoundManager.Instance.PlaySound(4);
				bool bShowDiceNumEff = false;
				if(person != boardPerson_me)
					bShowDiceNumEff = true;
				diceNumObj = UIManager.Instance.ShowDiceNumAbovePerson(person, ++nDice, 0, bShowDiceNumEff);//, offset_y);
				nDiceAddNum--;
				nCount++;
				timeAdd = 0.0f;
			}
			yield return null;
		}
		
		//diceIcon1.obj.transform.parent = diceNum.transform;
		//diceIcon2.obj.transform.parent = diceNum.transform;
		
		/*
		while(bTestPauseShowDiceUI)
			yield return null;

		yield return new WaitForSeconds(0.2f);

		foreach( GameObject go in diceOverHead)
		{
			Vector3 pos = diceNumObj.transform.localPosition;
			if(go.transform.localPosition.x<0)
			{
				pos.x += -0.1646941f;
				//pos.y += 0.1818451f;
				pos.y += 0.08f;
			}
			else
			{
				//pos.x += -0.3273217f;
				//pos.y += 0.0155863f;
				pos.x += -0.1646941f;
				pos.y -= 0.04f;
			}
			LeanTween.moveLocal(go, pos, 0.5f).setEase(LeanTweenType.easeInCubic);		
			LeanTween.scale(go, new Vector3(0.2f,0.2f,0.2f), 0.5f).setEase(LeanTweenType.easeInCubic);
			//LeanTween.rotateLocal(go, new Vector3(0,0,359), 0.5f).setEase(LeanTweenType.easeInCubic);
		}

		yield return new WaitForSeconds(1.0f);
		*/
		if(_isBattleDiceUI)
		{
			yield return new WaitForSeconds(0.5f);

			Vector3 [] diceIconPos = { Vector3.zero, Vector3.zero};

			foreach( GameObject go in diceOverHead)
			{
				Vector3 scaleTo = go.transform.localScale * 0.666f;
				Vector3 newPos = go.transform.localPosition;
				LeanTween.scale( go, scaleTo, 0.1f);
				if(newPos.x<0)
				{
					newPos.x += 0.05f;
					newPos.y -= 0.064f;
					LeanTween.moveLocal( go, newPos, 0.1f);
				}
				else
				{
					newPos.x -= 0.05f;
					newPos.y -= 0.064f;
					LeanTween.moveLocal( go, newPos, 0.1f);
				}
			}

			yield return new WaitForSeconds(0.1f);
			int i=0;
			foreach( GameObject go in diceOverHead)
			{
				diceIconPos[i] = go.transform.position;
				i++;
			}

			DeactivateDiceOverHead(false);

			if(isAttackerDiceUI)
			{
				BattleManager.Instance.ShowAttackerDiceIcon(diceIconPos);
			}
			else
			{
				BattleManager.Instance.ShowDefenderDiceIcon(diceIconPos);
			}

			battleNum.transform.parent = null;

			LeanTween.move( battleNum, battleNumPos, 0.2f).setEase(LeanTweenType.easeOutSine);


			//battleNum.transform.position = battleNumPos;

			yield return new WaitForSeconds(0.2f);

			//BattleManager.Instance.DetachDiceIcon();
			battleNum.transform.parent = person.transform;


			//yield return new WaitForSeconds(0.5f);

			isBattleDiceUIDoing = false;
			bWaitForUIBattleDice = false;
			isShowDiceUIDone = true;

			//diceNumObj.SetActive(false);
			bShowDiceNumCompleted = true;
			glog.debug ("Battle ShowDiceNum completed");
		}
		else
		{
			int nDiceToDest = nDice;
			if(person.IsAbnormalState(AbnormalType.MODIFY_MOVE_COST) )
			{
				int nParam = person.GetAbnormalParam(AbnormalType.MODIFY_MOVE_COST);
				nDiceToDest = (int)Math.Ceiling( nDice/(float)(nParam+1) );
				glog.debug( String.Format( "moveCOst  {0}  {1}  {2}",nDice,nDiceToDest,nParam) );
			}
			FindDestinationBoard(person, nDiceToDest);
			//bool isEscapeCheck = false;
			if(bEscapeToBind) {
				//isEscapeCheck = true;
				CardManager.Instance.ShowSkillNameEffect( CStringTableManager.Instance.GetItemById(1707) , person.transform);
				SoundManager.Instance.PlaySound(20);
				HudManager.Instance.ChangeFace( person.SID, true);
				bEscapeToBind = false;
			}

			bool isEscapeFail = false;
			if(bEscapeFailToBind) {
				//isEscapeCheck = true;
				CardManager.Instance.ShowSkillNameEffect( CStringTableManager.Instance.GetItemById(1706) , person.transform);
				HudManager.Instance.ChangeFace( person.SID, false);
				SoundManager.Instance.PlaySound(19);
				bEscapeFailToBind = false;
				person.ShowBoundObject();
				isEscapeFail = true;
			}		
			
			yield return new WaitForSeconds(0.3f);
			person.bShowMyTurnAlarm = false;
			isShowDiceUIDone = true;

			if(!isEscapeFail)
			{
				if(bActivatedDiceOverHead_byPlayAnim && !isBattleDiceUIDoing)
					DeactivateDiceOverHead(false);
			}

			yield return new WaitForSeconds(0.1f);
			
			if(!BattleManager.Instance.bCombatHappened)
				StageManagerWrapper.camControl.EventZoomOut();		
			
			
			
			yield return new WaitForSeconds( IngameSetting.Instance.DiceResultDelay);

			if(isEscapeFail)
			{
				if(bActivatedDiceOverHead_byPlayAnim && !isBattleDiceUIDoing)
					DeactivateDiceOverHead(false);
			}
			
			yield return new WaitForSeconds(0.2f);
			
			//Destroy(diceNum);
			if(isEscapeFail)
			{
				if(!isBattleDiceUIDoing)
					diceNumObj.SetActive(false);
			}
			
			bShowDiceNumCompleted = true;
			
			
			glog.debug ("ShowDiceNum completed");
		}
		
//		yield return new WaitForSeconds(0.4f);
						
//		yield return new WaitForSeconds(0.3f);
		
		
		

		//diceObj.GetComponent<UIDiceRollAnimation>().Reset();
		//NGUITools.SetActive(diceObj,false);
		
		
//		dicePair1.GetComponent<UIDiceRollAnimation>().Reset();
//		NGUITools.SetActive(dicePair1,false);
//		dicePair2.GetComponent<UIDiceRollAnimation>().Reset();
//		NGUITools.SetActive(dicePair2,false);
		
		
		//diceNumLabel.GetComponent<PlayMakerFSM>().enabled = false;
		//diceNumLabel.GetComponent<PlayMakerFSM>().Fsm.Reset();
		
//		NGUITools.SetActive(diceNumLabel,false);
		
		
		//diceOneNum.GetComponent<PlayMakerFSM>().enabled = false;
		//diceOneNum.GetComponent<PlayMakerFSM>().Fsm.Reset();
		
		
//		NGUITools.SetActive(diceOneNum,false);
//		NGUITools.SetActive(mainCharMoveNum,false);		

	}

//	public void HideDiceNum()
//	{
//		Destroy(diceNum);
//		DeactivateDiceOverHead();
//	}
	
	
	/*
	IEnumerator ShowDiceNumLabel(int nAddNum)
	{	
		yield return new WaitForSeconds(1.2f);
		isShowDiceUIDone = true;
		if(nAddNum>0) {
			glog.debug ("ShowDiceNumLabel "+diceObj.activeSelf);
			NGUITools.SetActive(diceNumLabel,true);
			diceNumLabel.GetComponent<UILabel>().text = "+"+nDiceAddNum.ToString();
		}
		Invoke ("HideDiceUI", 0.8f);
	}
	
	
	void HideDiceUI()
	{
		isShowDiceUIDone = true;
		glog.debug ("HideDiceUI");
		diceObj.GetComponent<UIDiceRollAnimation>().Reset();
		NGUITools.SetActive(diceObj,false);
		NGUITools.SetActive(diceNumLabel,false);
		if(diceNumLabel.GetComponent<PlayMakerFSM>()!=null)
			diceNumLabel.GetComponent<PlayMakerFSM>().enabled = false;
		NGUITools.SetActive(diceOneNum,false);
		if(diceOneNum.GetComponent<PlayMakerFSM>()!=null)
			diceOneNum.GetComponent<PlayMakerFSM>().enabled = false;
		NGUITools.SetActive(mainCharMoveNum,false);
		
	}
	*/
	/*
	public void ShowDice(int nDice, int nAddNum)
	{
		glog.debug ("showDice "+nDice+" nAddNum="+nAddNum);
		nDiceAddNum = nAddNum;
		if(bDice3D) {
			diceObj = dice3d;
		}
		else {
			diceObj = dice2d;
		}
		
		diceObj.SetActive(true);
		foreach(Transform child in diceObj.transform) {
			if( child.gameObject.tag == "Dice") {
				if(bDice3D) {
					child.gameObject.GetComponent<Animation>().Play();
				}
				else {
					string animName = "Roll"+nDice;
					child.gameObject.GetComponent<tk2dSpriteAnimator>().Play(animName);
					//child.gameObject.GetComponent<tk2dSpriteAnimator>().AnimationEventTriggered += DiceAnimationEventHandler;
					child.gameObject.GetComponent<tk2dSpriteAnimator>().AnimationCompleted = OnDiceAnimationComplete;
				}
			}
			else if( child.gameObject.tag == "Dice Num Label") {
				diceNumLabel = child.gameObject;
				diceNumLabel.GetComponent<tk2dTextMesh>().text = nDice.ToString();
				diceNumLabel.GetComponent<tk2dTextMesh>().Commit();
				
				if(nDiceAddNum>0) {
					
					diceNumLabel.transform.GetChild(0).GetComponent<tk2dTextMesh>().text = "+"+nDiceAddNum.ToString();
					diceNumLabel.transform.GetChild(0).GetComponent<tk2dTextMesh>().Commit();
				}
			}
		}
	}
	
	IEnumerator ShowDiceNumLabel()
	{
		float sumTime = 0.0f;
		while(sumTime<0.2f)
		{
			sumTime += Time.deltaTime; 
			yield return null;
		}		
		diceNumLabel.SetActive(true);
		
		sumTime = 0.0f;
		while(sumTime<0.3f)
		{
			sumTime += Time.deltaTime; 
			yield return null;
		}		
		if(nDiceAddNum>0)
			diceNumLabel.transform.GetChild(0).gameObject.SetActive(true);
		else
			diceNumLabel.transform.GetChild(0).gameObject.SetActive(false);
		
		sumTime = 0.0f;
		while(sumTime<0.4f)
		{
			sumTime += Time.deltaTime; 
			yield return null;
		}		
		HideDice();
	}
	
	public void HideDice()
	{
		diceNumLabel.SetActive(false);
		diceNumLabel.transform.GetChild(0).gameObject.SetActive(false);
		diceObj.SetActive(false);
	}*/
	
	
	/*
	IEnumerator ShowDiceLabel()
	{
		float sumTime = 0.0f;
		while(true)
		{
			sumTime += Time.deltaTime;
			if(sumTime>1.0f)
				break;
			yield return null;
		}
		
		diceNumLabel.SetActive(true);
	}
	*/
	
//	void DiceAnimationEventHandler(tk2dSpriteAnimator animator, tk2dSpriteAnimationClip clip, int frameNum)
//	{
//		string str = animator.name + " " + clip.name + " " + "INFO: " + clip.GetFrame(frameNum).eventInfo;
//		glog.debug(str);		
//		if(clip.GetFrame(frameNum).eventInfo == "particle") {
//			GameObject go = Instantiate(diceGroundEffectPrefab, new Vector3(0,0,0),Quaternion.identity) as GameObject;
//			go.transform.parent = animator.gameObject.transform;
//			Destroy(go,2.0f);
//		}
//	}
	/*
	void OnDiceAnimationComplete(tk2dSpriteAnimator animator, tk2dSpriteAnimationClip clip)
	{
		//string str = animator.name + " " + clip.name + " " + "INFO: " + clip.GetFrame(frameNum).eventInfo;
		//string str = animator.name + " " + clip.name;
		//glog.debug(str);
		StartCoroutine("ShowDiceNumLabel");
		animator.AnimationCompleted = null;
	}*/
	
	public void SendLeave()
	{
		StageManagerWrapper.SendLeave();
	}
	
	public void ShowPVERewardWindow()
	{
		UIManager.Instance.CreateSelectRewardUI(true);
	}
	
	public void ShowGameOver(bool isPvp, int runnerCount, int [] rankList, int [] sidList, int [] pvpPoint, int [] pvpDelta, GameOverType gameOverType)
	{
		//string strWin = "YOU LOSE!";
		//if(isWinGame)
		//	strWin = "YOU WIN!";
		
	    //GameObject go = Instantiate(victoryPrefab) as GameObject;
		
	    //go.GetComponent<tk2dTextMesh>().text = strWin;
	    //go.GetComponent<tk2dTextMesh>().Commit();
	    //Destroy(go, 5.0f);		
		if(!isGameOver)
			return;
		isGameOver = false;
		
		HudManager.Instance.StopAllTurnAlarmAndGear();
		
		//UIManager.Instance.ShowMainHud(false);
		
		
		if(isWinGame) {
			SoundManager.Instance.PlaySound(41);
		}
		else
		{
			SoundManager.Instance.PlaySound(42);
		}

        if (!isPvp)
        {
            CSceneManager.isSingleGame = true;
        //    if(isWinGame)
        //        Invoke("ShowPVERewardWindow", 2.0f);
        //    else
        //        Invoke("SendLeave", 3.0f);
        //    return;
        }
		
		StartCoroutine( CoGameOverPvp(runnerCount, rankList, sidList, pvpPoint, pvpDelta, gameOverType) );
		

		
//		boardPersonPCList.Sort(
//		    delegate(BoardPerson p1, BoardPerson p2)
//		    {
//		        return p2.curBoardTile.boardInfo.pathInfo[p2.mypath].ratioToGoal.CompareTo(p1.curBoardTile.boardInfo.pathInfo[p1.mypath].ratioToGoal);
//		    }
//		);
//		for(int i=0; i<boardPersonPCList.Count; i++)
//		{
//			UIManager.Instance.SetGameResultRank( i , boardPersonPCList[i]);
//				
//			if(boardPersonPCList[i].isMe)
//			{
//				UIManager.Instance.SetMyRankFrame(i);
//			}
//		}
		
	}
	
	IEnumerator CoGameOverPvp(int runnerCount, int [] rankList, int [] sidList, int [] pvpPoint, int [] pvpDelta, GameOverType gameOverType)
	{
        GameObject victoryAnimation = null;
		for(int i=0; i< runnerCount; i++)
		{	
			int nRank = rankList[i];
			int sid = sidList[i];
			StageManagerWrapper.GetBoardPerson(sid).myFinalRank = nRank;
		}
		for(int i=0; i< runnerCount; i++)
		{	
			int nRank = rankList[i];
			int sid = sidList[i];
			if(nRank==1)
			{
                victoryAnimation = LTPrefabManager.InstantiatePrefab(PrefabTypes.Fx_VictoryIngame01, Vector3.zero, Quaternion.identity);
                victoryAnimation.transform.parent = UIManager.Instance.centerAnchor.transform;
                victoryAnimation.transform.localPosition = Vector3.zero;
                victoryAnimation.transform.localScale = LTPrefabManager.GetPrefabOriginalScale(PrefabTypes.Fx_VictoryIngame01);
				UIManager.Instance.ShowFinishPopUp( StageManagerWrapper.GetBoardPerson(sid).nickName , gameOverType  );                

				StageManagerWrapper.camControl.SetCameraFocus( StageManagerWrapper.GetBoardPerson(sid).transform);
				if( StageManagerWrapper.GetBoardPerson(sid).IsMovingOrWaitMoving() )
					StageManagerWrapper.GetBoardPerson(sid).bWaitForVictoryGame = true;
				else
					StageManagerWrapper.GetBoardPerson(sid).PlayVictoryAnim(2);
				yield return new WaitForSeconds(3.0f);
				StageManagerWrapper.GetBoardPerson(sid).ShowDestMark(false);
				UIManager.Instance.ResetFinishPopUp();
				break;
			}
		}

        yield return new WaitForSeconds(.5f);
		
		//NGUITools.SetActive(UIManager.Instance.gameResultUI, true);
		if(victoryAnimation!=null)
        	victoryAnimation.SetActive(false);
		//UIManager.Instance.CreateGameResultUI();
		
		glog.debug("runnercount="+runnerCount);

        List< Hashtable> param = new List<Hashtable>();

		//int nRankMax = 0;
		for(int i=0; i< runnerCount; i++)
		{
            Hashtable data = new Hashtable();
            data.Add("rank", rankList[i]);
            data.Add("BoardPerson", StageManagerWrapper.GetBoardPerson(sidList[i]));
            data.Add("Point", pvpPoint[i]);
            data.Add("Delta", pvpDelta[i]);

            param.Add(data);
            //int nRank = rankList[i];
            //int sid = sidList[i];
            //glog.debug("nRank="+nRank+"  sid="+sid);
            //if(nRank>0) // 0이면 리타이어
            //{
            //    if(nRank>runnerCount)
            //    {
            //        Debug.LogError("nRank over runnercount...");
            //        continue;
            //    }
            //    nRankMax = Math.Max(nRankMax, nRank);
            //    UIManager.Instance.SetGameResultRank( nRank-1 , StageManagerWrapper.GetBoardPerson(sid) , false);
            //    if(sid == mySID)
            //        UIManager.Instance.SetMyRankFrame(nRank-1);
            //    UIManager.Instance.SetPvpPoint(nRank-1, pvpPoint[i], pvpDelta[i]);
            //}
		}

        Popup_IngameRanking sc = PopupManager.PopupPush(PopupKind.Popup_IngameRanking) as Popup_IngameRanking;
        sc.SetPopupWithData(param, mySID);
        ////리타이어된애처리
        //for(int i=0; i< runnerCount; i++)
        //{
        //    int nRank = rankList[i];
        //    int sid = sidList[i];
        //    if(nRank==0)
        //    {
        //        UIManager.Instance.SetGameResultRank( nRankMax, StageManagerWrapper.GetBoardPerson(sid) , true);
        //        if(sid == mySID)
        //            UIManager.Instance.SetMyRankFrame(nRankMax);
        //        UIManager.Instance.SetPvpPoint(nRankMax, pvpPoint[i], pvpDelta[i]);		
        //        nRankMax++;
        //    }
        //}		
	}
	
	
	public void ShowUIOnPerson(UIType uiType , BoardPerson parent)
	{
		GameObject screenSimpleTextGo = screenSimpleTextGo1;
		
		if(screenSimpleTextGo1.activeSelf)
		{
			if(screenSimpleTextGo2==null)
				screenSimpleTextGo2 = Instantiate(screenSimpleTextPrefab) as GameObject;
			
			screenSimpleTextGo = screenSimpleTextGo2;
		}
		
		screenSimpleTextGo.GetComponent<UILabel>().text = uiString[uiType];
		screenSimpleTextGo.transform.position = new Vector3(parent.transform.position.x, parent.transform.position.y + BoardPerson.upOffset, screenSimpleTextPrefab.transform.position.z);
		screenSimpleTextGo.transform.parent = parent.transform;
		screenSimpleTextGo.SetActive(true);
	}
	
	public void ShowGlowTileEffect(BoardTile tile)
	{
		isGlowTileForPathSelect = true;
		StartCoroutine(GlowTileEffect(tile));
	}
	
	IEnumerator GlowTileEffect(BoardTile tile)
	{
		tk2dSprite tileSprite = tile.GetComponent<tk2dSprite>();
		Color reserveColor = tileSprite.color;
		float alpha = 1.0f;
		float alpha_delta = -1.0f;
		while(isGlowTileForPathSelect)
		{
			alpha += alpha_delta * Time.deltaTime;
			if(alpha <0.5f) {
				alpha = 0.5f;
				alpha_delta = -alpha_delta;
			}
			if(alpha >1.0f) {
				alpha = 1.0f;
				alpha_delta = -alpha_delta;
			}
			tileSprite.color = new Color(reserveColor.r*alpha, reserveColor.g*alpha, reserveColor.b*alpha, reserveColor.a);
			yield return null;
		}
		tileSprite.color = reserveColor;
	}	
	
	
	public void StartMovePawn(BoardPerson person, int moveCount, int[] path, bool isBackWard)
	{
		StartCoroutine(DoStartMovePawn(person, moveCount, path , isBackWard));
	}
	
	IEnumerator DoStartMovePawn(BoardPerson person, int moveCount, int[] path, bool isBackWard)
	{
		while( person.moveState == BoardPerson.MoveState.WaitMoving)
			yield return null;
		personToMove = person;
		person.moveState = BoardPerson.MoveState.WaitMoving;
		isWaitingForBoardPersonMoving = true;
		//yield return new WaitForSeconds(1.4f);
		if(isBackWard)
		{
			if( person.bUseSkill_BackMove)
			{
				CardManager.Instance.ShowSkillNameEffect(CStringTableManager.Instance.GetItemById(1667), person.transform);
				person.bUseSkill_BackMove = false;
			}
			else
			{
				while( person.IsMovingOrWaitMoving() || !BattleManager.Instance.isBattleResultDone  )
				{
					if(person.isBackExpelled)
					{
						break;
					}
					if(person.isDamagedAnimCompleted)
					{
						person.isDamagedAnimCompleted = false;
						break;
					}
					yield return null;
				}
			}			
		}
		glog.debug("StartMovePawn");
		while(!isShowDiceUIDone)
		{
			yield return null;
		}

		if(isBackWard)
			glog.debug (person.SID+" ========== back Move=========== "+person.pawnType);
		else
			glog.debug (person.SID+"========== forward Move=========== "+person.pawnType);
		if(person.isMe)
        	Camera.main.gameObject.GetComponent<CameraControl>().SetCameraFocus(person.transform);
		isWaitingForBoardPersonMoving = false;
		person.StartMoveTo(moveCount, path,isBackWard, false);
	}
	
	
	
	
	public void ShowUIRollMoveDice()
	{
		curTurnSID = mySID;
		Debug.LogError (" Old Version dont use this   SHOW_UI : UI_ROLL_MOVE_DICE   ");
		//EnemyUnitUI.Instance.HidePanel();
		if (isBoardPersonMoving)
			waitRollBtnShow = true;
		else
			UIManager.Instance.ShowMoveRollButton(true);
		
		if (CSceneManager.BuilderIsOn)
		{
			CSceneManager.BuilderStatus = 1;
		}		
	}

	public void ShowUIRollMoveDice(DateTime deadLine)
	{
		StartCoroutine( CoShowUIRollMoveDice(deadLine) );
	}
	
	
	IEnumerator CoShowUIRollMoveDice(DateTime deadLine)
	{
		nCountShowUIRollMoveDice++;
		curTurnSID = mySID;
		glog.debug(" SHOW_UI : UI_ROLL_MOVE_DICE     deadLine");
		//EnemyUnitUI.Instance.HidePanel();
		if (isBoardPersonMoving)
		{
			deadLineReserve = deadLine;
			waitRollBtnShow = true;
		}
		else
		{
			while(bDuringRebirth)
				yield return null;
			if(nCountShowUIRollMoveDice>=2)
			{
				boardPerson_me.DeterminAnimFromCurTile(false);
				//UIManager.Instance.EnableAllBtnTemporary(false);
				StageManagerWrapper.camControl.SetCameraFocusMe();
				yield return new WaitForSeconds(1.5f);
			}
			UIManager.Instance.ShowMoveRollButton(true, deadLine);
		}

		if (CSceneManager.BuilderIsOn)
		{
			CSceneManager.BuilderStatus = 1;
		}		
	}
	
	public static float CalcZFromYTile( float y)
	{
		return y * 0.1f;
	}
	
	public static float CalcPlayerZFromTile( float tile_z, int order, bool isMe, bool isMoving)
	{
		order = order % 8 + 1;
		if(isMe)
			order = 9;
		else if(isMoving)
			order = 8;
		float offset = order*0.001f;
		
		//return tile_z - 0.001f - offset;
		return tile_z - 2 - offset;
	}

	public static float CalcPlayerZFromTile_Start( float tile_z, int order)
	{
		float offset = 0;
		if(order==1 || order==3)
			offset = 0;
		else if(order==2)
			offset = 0.01f;
		else if(order==4)
			offset = -0.01f;
		
		//return tile_z - 0.001f - offset;
		return tile_z - 2 - offset;
	}

	public static float CalcPlayerZFromSameTile( float tile_z, bool isFront)
	{
		int order = 8;
		if(isFront)
			order = 9;
		float offset = order*0.001f;
		
		//return tile_z - 0.001f - offset;
		return tile_z - 2 - offset;
	}
	
	public static float CalcZFromY_PlayerFront( float player_z)
	{
		return player_z - 0.01f;
	}
	
	public static float CalcZFromY_PlayerBack( float player_z)
	{
		return player_z + 0.01f;
	}
	
	public void ChangeBoardStatus(int boardID, int height, int boardDataType, BoardPerson person, ChangeBoardReason changeReason)
	{
		BoardTile bt = PathManager.Instance.GetBoardTile(boardID);

		bt.ChangeBoardStatus(height, boardDataType, person, changeReason);
			//RestartFSM( FindFsm(bt.gameObject, "shakeAndUp") );

		
	}
	
	
	public void ActivateDiceOverHead(BoardPerson person, DiceShapeType diceTypeToChange)
	{
		if(person.gameObject.renderer.enabled==false)
			return;
		if( person_activatedDiceOverHead == person)
			return;
		if(diceTypeToChange == DiceShapeType.Defender && person.SID != curTurnSID)
		{
			person.PlayAlarmParticle();
		}

		if(diceTypeToChange == DiceShapeType.Attacker)
			person.ReCalculateZ_SameTileBattle();

		if(person_activatedDiceOverHead!=null && person_activatedDiceOverHead.bActivateDiceOverHead)
			person_activatedDiceOverHead.bActivateDiceOverHead = false;

		bActivatedDiceOverHead_byPlayAnim = false;
		//nCountShowUIRollMoveDice++;
		int index = 0;
		foreach( GameObject go in diceOverHead)
		{
			go.transform.parent = person.transform;
			go.SetActive(true);
			ChangeDiceTexture(go, diceTypeToChange);
			Vector3 newPos = diceOverHeadPrefab.transform.position;
			newPos.y += person.overHeadDiceOffset;
			go.transform.localPosition = newPos;
			go.transform.localScale = diceOverHeadPrefab.transform.localScale;
			go.transform.Find("dice_ani").animation.Play("dice_start");
			if(index!=0)
				go.SetActive(false);
			index++;
		}
		curDiceShapeType = diceTypeToChange;
		person.bActivateDiceOverHead = true;
		person_activatedDiceOverHead = person;
	}

	public void DeactivateDiceOverHead(bool bForceDeactivate)
	{
		bActivatedDiceOverHead_byPlayAnim = false;
		//nCountShowUIRollMoveDice--;
		//if(!bForceDeactivate && nCountShowUIRollMoveDice>0)
		//	return;
		nCountShowUIRollMoveDice=0;
		foreach( GameObject go in diceOverHead)
		{
			go.transform.parent = null;
			go.SetActive(false);		
		}
		person_activatedDiceOverHead = null;
	}

	Texture GetDiceTexture(DiceShapeType diceType)
	{
		return IngameSetting.Instance.GetDiceTexture(diceType);
	}

	void ChangeDiceTexture(GameObject go, DiceShapeType diceType)
	{
		if(!IngameSetting.Instance.bChangeDiceTexture)
			return;
		if(diceType == curDiceShapeType)
			return;
		MeshRenderer ren = go.GetComponentInChildren<MeshRenderer>();
		if(ren!=null)
		{
			ren.material.mainTexture = GetDiceTexture(diceType);
		}
	}

	public void HideDiceTemporarily(bool bHide)
	{
		foreach( GameObject go in diceOverHead)
		{
			MeshRenderer ren = go.GetComponentInChildren<MeshRenderer>();
			if(ren!=null)
				ren.enabled = !bHide;
		}
	}
	
	public float GetDiceOverHeadAnimLength()
	{
		foreach( GameObject go in diceOverHead)
		{
			return go.transform.Find("dice_ani").animation["dice_up01_01"].length;
		}
		return 1.0f;
	}

	IEnumerator CoPlayDiceOverHeadAnim(int [] nDice, BoardPerson person, bool isOneDice)
	{

		HudManager.Instance.SetTurnTimeCount(person.SID,false);

		if(!person.bActivateDiceOverHead)
			ActivateDiceOverHead(person, DiceShapeType.Normal);
		person.bActivateDiceOverHead = false;
		int index=0;
		float offset_x = diceOverheadOffsetX;
		SoundManager.Instance.PlaySound(2);
		int numberOfDice = numDice;
		if(isOneDice)
		{
			numberOfDice = 1;
			hitAnimDelayBetweenDice=0;
		}
		else
		{
			//hitAnimDelayBetweenDice=0.0f;
			hitAnimDelayBetweenDice = 0.2f;//UnityEngine.Random.Range(0.1f, 0.3f);
		}
		
		bActivatedDiceOverHead_byPlayAnim = true;
		
		foreach( GameObject go in diceOverHead)
		{
			if(isOneDice && index==1)
			{
				go.SetActive(false);
				break;
			}
			
			//init
			Vector3 newPos = diceOverHeadPrefab.transform.position;
			newPos.y += person.overHeadDiceOffset;
			go.transform.localPosition = newPos;
			go.transform.localScale = diceOverHeadPrefab.transform.localScale;
			
			
			Vector3 destPos = go.transform.localPosition;
			if(index==0)
			{
				//EffectManager.Instance.PlayEffectZ(17, go.transform.position);
				EffectManager.Instance.PlayEffectParent(17, person.transform);
				EffectManager.Instance.fxobj[17].transform.localPosition = destPos;
				EffectManager.Instance.DisableParticle(17,2.0f);
				//Destroy(effGo, 3.0f);		
			}
			
			go.SetActive(true);
			if(numberOfDice%2==0)
			{
				destPos.x += offset_x * ( (int)(index/2) + 1);
				offset_x = -offset_x;
			}
			else
			{
				if(index!=0)
				{
					destPos.x += offset_x * ( (int)( (index-1)/2 ) + 1);
					offset_x = -offset_x;				
				}
			}
			glog.debug(index+"   PlayDiceOverHeadAnim   "+destPos);
			if(isOneDice)
			{
				Invoke("PreDoneDirectionDiceRoll", GetDiceOverHeadAnimLength() +0.2f);
				Invoke("DoneDirectionDiceRoll", GetDiceOverHeadAnimLength() +1.0f);
			}
			else
				iTween.MoveTo( go, iTween.Hash("position", destPos,"islocal",true, "time",0.5f,"easetype","easeInSine") );
			if(index==0)
				go.transform.Find ("dice_ani").animation.Play("dice_up0" + nDice[index].ToString()+"_01");		
			else
				go.transform.Find ("dice_ani").animation.Play("dice_up0" + nDice[index].ToString()+"_01");		
			index++;
			if(hitAnimDelayBetweenDice>0)
				yield return new WaitForSeconds(hitAnimDelayBetweenDice);
		}
	}

	public void PlayDiceOverHeadAnim(int [] nDice, BoardPerson person, bool isOneDice)
	{
		StartCoroutine(CoPlayDiceOverHeadAnim(nDice, person, isOneDice) );
	}
	
	/*
	public void SetCaseRecoverMP(int val)
	{
		bCaseRecoverMP = true;
		caseMPToRecover = val;
	}
	
	public void SetOtherPlayerCaseRecoverMP(int other_sid, int val)
	{
		bCaseRecoverMP = true;
		glog.debug("SetOtherPlayerCaseRecoverMP  "+other_sid+"   "+val);
//		if( otherPlayerCaseRecoverMP.ContainsKey(other_sid) )
//		{
//			Debug.LogError(" SetOtherPlayerCaseRecoverMP already exist  "+other_sid);
//			otherPlayerCaseRecoverMP[other_sid] = val;
//		}
//		else
//		{
			otherPlayerCaseRecoverMP.Add (  new SidMpPair(other_sid, val)  );
			glog.debug("added  otherPlayerCaseRecoverMP "+otherPlayerCaseRecoverMP.Count);
//		}
	}	
	*/
	public void WaitForDirectionRoll(int sid, int diceValue, int nextBoardID)
	{
		UIManager.Instance.HideGaugeRoll();
		bWaitForDirectionRollDone = true;
		diceValue_direction = diceValue;
		if( StageManagerWrapper.GetBoardPerson(sid).IsMovingOrWaitMoving() )
			StageManagerWrapper.GetBoardPerson(sid).bWaitDirectionRoll = true;
		else
			StageManagerWrapper.GetBoardPerson(sid).RollDirectionDice();
	}


	void PreDoneDirectionDiceRoll()
	{
		SoundManager.Instance.PlaySoundDiceNum(diceValue_direction);
		UIManager.Instance.EffectDirectionDice(diceValue_direction);
	}

	void DoneDirectionDiceRoll()
	{
		bWaitForDirectionRollDone = false;
		if(bActivatedDiceOverHead_byPlayAnim)
			DeactivateDiceOverHead(false);
	}

	public void ShowDestMark(int gameOrder, BoardTile tile, int markCount)
	{
		if(markCount>= destShowEffect.Length)
			return;

		Vector3 newPos = tile.GetTileCenter();
		newPos.y += 0.191527f;		//0.25f;
		newPos.z = destMark.transform.position.z;

		if(destShowEffect[markCount]==null)
		{
			destShowEffect[markCount] = Instantiate(destMark) as GameObject;
			destShowEffect[markCount].name = "destmark";
			destShowEffect[markCount].SetActive(false);
		}
		if(!destShowEffect[markCount].activeSelf && !destShowEffect[markCount].GetComponent<DestinationMark>().isDiscarded)
		{
			destShowEffect[markCount].transform.position = newPos;
			destShowEffect[markCount].SetActive(true);
			if(gameOrder>=1 && gameOrder<=4)
				destShowEffect[markCount].GetComponent<ParticleSystem>().renderer.material.mainTexture = IngameSetting.Instance.fxPointerTexture[gameOrder-1];
			destShowEffect[markCount].GetComponent<ParticleSystem>().Play();
			destShowEffect[markCount].transform.parent = tile.transform;
		}
	}

	public void DiscardDestMark(GameObject markToDiscard)
	{
		for(int i=0; i< destShowEffect.Length; i++)
		{
			if(destShowEffect[i]==markToDiscard)
			{
				destShowEffect[i].GetComponent<ParticleSystem>().Stop();
				destShowEffect[i].SetActive(false);
				destShowEffect[i].transform.parent = null;
				destShowEffect[i].GetComponent<DestinationMark>().isDiscarded = true;
				break;
			}
		}
	}

	public void HideDestMark()
	{
		for(int i=0; i< destShowEffect.Length; i++)
		{
			if(destShowEffect[i]!=null)
			{
				destShowEffect[i].GetComponent<ParticleSystem>().Stop();
				destShowEffect[i].SetActive(false);
				destShowEffect[i].transform.parent = null;
				destShowEffect[i].GetComponent<DestinationMark>().isDiscarded = false;
				if(i>1)
				{
					Destroy(destShowEffect[i]);
					destShowEffect[i]=null;
				}
			}

		}
	}

	void HideCurActiveDestMark()
	{
		curActiveDestMark.Clear ();
		for(int i=0; i< destShowEffect.Length; i++)
		{
			if(destShowEffect[i]!=null && destShowEffect[i].activeSelf)
			{
				if(!curActiveDestMark.Contains(destShowEffect[i]))
				{
					curActiveDestMark.Add(destShowEffect[i]);
					destShowEffect[i].SetActive(false);
				}
			}
		}
	}

	public void ShowCurActiveDestMark()
	{
		foreach(GameObject markGo in curActiveDestMark)
		{
			markGo.SetActive(true);
		}
	}

	void FindDestinationBoard(BoardPerson person, int nDice)
	{
		for(int i=0; i< destShowEffect.Length; i++)
		{
			if(destShowEffect[i]!=null)
				destShowEffect[i].GetComponent<DestinationMark>().isDiscarded = false;
		}
		destinationTiles.Clear();
		boardIdsUntilDestTile.Clear();
		destinationTileBidDic.Clear ();
		nFindDestIterationCount=0;// when player is lap 1 and start exactly at goal, prevent IsLastTile check success
		FindDestBoard( person, person.curBoardTile, person.mypath, nDice);
	}
	
	void FindDestBoard(BoardPerson person, BoardTile btile, int mypath, int nDice)
	{
		nFindDestIterationCount++;
		boardIdsUntilDestTile.Push(btile);
		if(nDice<=0 || btile.IsLastTile(person,nFindDestIterationCount) )
		{
			if(!destinationTiles.Contains(btile))
			{
				destinationTiles.Add(btile);
				destinationTileBidDic.Add( btile, boardIdsUntilDestTile.ToList() );
			}
			boardIdsUntilDestTile.Pop ();
			return;
		}
		foreach( int nextBid in btile.boardInfo.pathInfo[mypath].forwardBoards )
		{
			int move_cost = 1;
			if( PathManager.Instance.GetBoardTile(nextBid).boardInfo.tilename == BoardInfo.TileName.road_bumpy_01)
				move_cost = 2;
			FindDestBoard( person, PathManager.Instance.GetBoardTile( nextBid) , mypath, nDice-move_cost);
		}
		if(boardIdsUntilDestTile.Count>0)
			boardIdsUntilDestTile.Pop ();

	}

}
